﻿using System;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using System.Runtime.Remoting.Messaging;
using StockTrader.FrontEnd.MarketViewer.DAL;
using StockTrader.FrontEnd.DataContract;
using StockTrader.BusinessService.DataContract.Mortgate;
using Mortgage.DAL;

namespace MortgageMonitor.BSL
{
    public class AsyncDataProcessor
    {
        private LoanRateData _item;

        private InsertRecord _invokeMe;
        private ProgressBar _progress;
        private Label _elapsed;
        private Label _remain;
        private Label _speed;
        private Label _percent;
        private Label _status;

        private Label _current;
        private int _numOfRecord;

        private DateTime _startTime;
        private int _totalRecord;

        private delegate void InsertRecord(LoanRateData item);

        public AsyncDataProcessor(LoanRateData item, ProgressBar progress, Label current, int numofrecord, DateTime starttime, int totalrecord, Label elapsed, Label remain, Label speed, Label percent, Label status)
        {
            _item = item;

            _progress = progress;
            _current = current;
            _numOfRecord = numofrecord;
            _startTime = starttime;
            _totalRecord = totalrecord;
            _elapsed = elapsed;
            _remain = remain;
            _speed = speed;
            _percent = percent;
            _status = status;

            _invokeMe = new InsertRecord(StaticDataAccess.InportLoadRate);
        }

        public void Execute()
        {
            try
            {
                //Update UI here
                _invokeMe.BeginInvoke(_item, this.CallBack, null);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
        private void CallBack(IAsyncResult ar)
        {
            try
            {
                AsyncResult result = (AsyncResult)ar;
                // grab the delegate
                InsertRecord del = (InsertRecord)result.AsyncDelegate;

                del.EndInvoke(ar);
                //Update UI here

                MethodInvoker updateUI = delegate
                {
                    int completed = Convert.ToInt32(_numOfRecord * 100.0 / _totalRecord);
                    _progress.Value = _numOfRecord;
                    _current.Text = _numOfRecord.ToString("N0");
                    _percent.Text = completed.ToString("N0");
                    if (completed.Equals(100))
                        _status.Text = "Đã cập nhật xong " + _numOfRecord.ToString() + " dòng.";
                };
                if (_progress.InvokeRequired || _current.InvokeRequired ||
                    _percent.InvokeRequired || _status.InvokeRequired)
                {
                    _progress.Invoke(updateUI);
                    _current.Invoke(updateUI);
                    _percent.Invoke(updateUI);
                    _status.Invoke(updateUI);
                }
                else
                    updateUI();

                MethodInvoker TimeRelatedParam = delegate
                {
                    TimeSpan execTime = DateTime.Now - _startTime;
                    int speed = Convert.ToInt32(_numOfRecord / execTime.TotalSeconds + 1);
                    _elapsed.Text = execTime.Minutes.ToString("00") + " : " +
                                    execTime.Seconds.ToString("00") + " : " +
                                    execTime.Milliseconds.ToString("00");

                    _speed.Text = speed.ToString();
                    TimeSpan estimateExec = new TimeSpan(0, 0, Convert.ToInt32((_totalRecord - _numOfRecord) / speed));
                    _remain.Text = estimateExec.Minutes.ToString("00") + " : " +
                                    estimateExec.Seconds.ToString("00") + " : " +
                                    estimateExec.Milliseconds.ToString("00"); ;

                };
                if (_elapsed.InvokeRequired || _remain.InvokeRequired || _speed.InvokeRequired)
                {
                    _elapsed.Invoke(TimeRelatedParam);
                    _remain.Invoke(TimeRelatedParam);
                    _speed.Invoke(TimeRelatedParam);
                }
                else
                    TimeRelatedParam();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
    }
}
